/* eslint-disable @typescript-eslint/indent */
/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { CapsuleItem } from '../../../../capsule/src/capsule.props';
import {
    DataGridHeaderCell,
    HeaderCellStatus,
    UseColumn,
    UseDataView,
    UseColumnFilter,
    UseFilterHistory,
    UseSort,
    UseVirtualScroll,
    UseFilter
} from '../../composition/types';

export default function (
    useColumnComposition: UseColumn,
    useDataViewComposition: UseDataView,
    useColumnFilterComposition: UseColumnFilter,
    useFilterComposition: UseFilter,
    useFilterHistoryComposition: UseFilterHistory,
    useSorterComposition: UseSort,
    useVirtualScrollComposition: UseVirtualScroll
) {
    const items: CapsuleItem[] = [
        { name: '升序', value: 'asc', icon: 'f-icon f-icon-col-ascendingorder' },
        { name: '无', value: 'none' },
        { name: '降序', value: 'desc', icon: 'f-icon f-icon-col-descendingorder' }
    ];

    function clearSortStatus(headerCell: DataGridHeaderCell) {
        const cellStatus = headerCell.status;
        const hasSorted = (cellStatus & HeaderCellStatus.sorted) === HeaderCellStatus.sorted;
        const hasAscending = (cellStatus & HeaderCellStatus.ascending) === HeaderCellStatus.ascending;
        const hasDecending = (cellStatus & HeaderCellStatus.descending) === HeaderCellStatus.descending;
        let originalStatus = hasSorted ? cellStatus ^ HeaderCellStatus.sorted : cellStatus;
        originalStatus = hasAscending ? originalStatus ^ HeaderCellStatus.ascending : originalStatus;
        originalStatus = hasDecending ? originalStatus ^ HeaderCellStatus.descending : originalStatus;
        return originalStatus;
    }

    function clearSort(headerCell: DataGridHeaderCell) {
        headerCell.sortType = 'none';
        headerCell.status = clearSortStatus(headerCell);
        const targetColumn = headerCell.column;
        if (targetColumn) {
            targetColumn.sort = 'none';
            targetColumn.sortOrder = 0;
            useColumnComposition.applyColumnSorter(useDataViewComposition, useSorterComposition);
        }
    }

    function onClear($event: MouseEvent, headerCell: DataGridHeaderCell) {
        headerCell.filterValue = null;
        useDataViewComposition.removeFilter(`field_filter_${headerCell.field}`);
        clearSort(headerCell);
    }

    function updateSortStatus(headerCell: DataGridHeaderCell) {
        const originalStatus = clearSortStatus(headerCell);
        const finalStatus =
            headerCell.sortType === 'none'
                ? originalStatus
                : headerCell.sortType === 'asc'
                ? originalStatus | HeaderCellStatus.sorted | HeaderCellStatus.ascending
                : originalStatus | HeaderCellStatus.sorted | HeaderCellStatus.descending;
        headerCell.status = finalStatus;
        const targetColumn = headerCell.column;
        if (targetColumn) {
            targetColumn.sort = headerCell.sortType;
            targetColumn.sortOrder = headerCell.sortType !== 'none' ? targetColumn.sortOrder : 0;
            headerCell.status = finalStatus;
            useColumnComposition.applyColumnSorter(useDataViewComposition, useSorterComposition);
        }
    }

    function updateFilterStatus(headerCell: DataGridHeaderCell) {
        const hasFilteredStatus = (headerCell.status & HeaderCellStatus.filtered) === HeaderCellStatus.filtered;
        headerCell.status = hasFilteredStatus
            ? headerCell.status ^ HeaderCellStatus.filtered
            : headerCell.status | HeaderCellStatus.filtered;
        const hasSetFilter = headerCell.filterValue != null && headerCell.filterValue !== '' && headerCell.filter;
        if (hasSetFilter) {
            useFilterComposition.addColumnFilter(headerCell);
            useDataViewComposition.refresh();
        } else {
            useFilterComposition.removeColumnFilter(headerCell);
            useDataViewComposition.refresh();
        }
    }

    function onConfirm($event: MouseEvent, headerCell: DataGridHeaderCell) {
        headerCell.showPopover = false;
        headerCell.filterHistory = undefined;
        useFilterHistoryComposition.updateFilterHistory(headerCell, headerCell.filterValue);
        updateFilterStatus(headerCell);
        updateSortStatus(headerCell);
        useVirtualScrollComposition.reCalculateVisualDataRows();
    }

    function resetSortTypeByStatus(headerCell: DataGridHeaderCell) {
        const cellStatus = headerCell.status;
        const hasSorted = (cellStatus & HeaderCellStatus.sorted) === HeaderCellStatus.sorted;
        const hasAscendSorted = hasSorted && (cellStatus & HeaderCellStatus.ascending) === HeaderCellStatus.ascending;
        headerCell.sortType = hasSorted ? (hasAscendSorted ? 'asc' : 'desc') : 'none';
        useSorterComposition.updateSorter(headerCell, useDataViewComposition);
    }

    function onCancel($event: MouseEvent, headerCell: DataGridHeaderCell) {
        headerCell.showPopover = false;
        headerCell.filterHistory = undefined;
        resetSortTypeByStatus(headerCell);
    }

    function renderFilterContainer(headerCell: DataGridHeaderCell) {
        return (
            <div class="fv-column-sort-filter-container">
                <div class="fv-column-sort-section">
                    <f-capsule items={items} v-model={headerCell.sortType} type="secondary"></f-capsule>
                </div>
                <div class="fv-column-filter-section">
                    <div class="fv-column-filter-section-title">筛选</div>
                    <div class="fv-column-filter-section-editor">{useColumnFilterComposition.getFilterEditor(headerCell)}</div>
                </div>
                <div class="fv-column-sort-filter-footer">
                    <div class="fv-column-clear-section">
                        <f-button
                            style="margin: 5px 0;padding-left: 0;"
                            type="link"
                            onClick={(payload: MouseEvent) => onClear(payload, headerCell)}>
                            清空
                        </f-button>
                    </div>
                    <div class="fv-column-confirm-section">
                        <f-button style="margin: 5px;width: 48px;" onClick={(payload: MouseEvent) => onConfirm(payload, headerCell)}>
                            确定
                        </f-button>
                        <f-button
                            style="margin: 5px;width: 48px;"
                            type="secondary"
                            onClick={(payload: MouseEvent) => onCancel(payload, headerCell)}>
                            取消
                        </f-button>
                    </div>
                </div>
            </div>
        );
    }

    return { renderFilterContainer };
}
